package com.google.zxing.client.ohos.component;

import com.google.zxing.ResultPoint;
import com.google.zxing.client.ohos.camera.CameraManager;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.media.image.PixelMap;

import java.util.ArrayList;
import java.util.List;


public class FinderComponent extends Component implements AnimatorValue.ValueUpdateListener{
    private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
    private static final long ANIMATION_DELAY = 80L;
    private static final int CURRENT_POINT_OPACITY = 0xA0;
    private static final int MAX_RESULT_POINTS = 20;
    private static final int POINT_SIZE = 6;

    private final int maskColor = 0x606060;//遮罩
    private final int resultColor = 0xb0000000;//结果
    private final int laserColor = 0xffcc0000;//激光
    private final int resultPointColor = 0xc0ffbd21;//
    private int scannerAlpha = 0;

    private List<ResultPoint> possibleResultPoints;
    private List<ResultPoint> lastPossibleResultPoints;

    private CameraManager cameraManager;

    private Paint paint;
    private boolean result = false;
    private RectFloat topRect;
    private RectFloat leftRect;
    private RectFloat rightRect;
    private RectFloat bottomRect;

    private PixelMapHolder resultPixelMapHolder;

    private Rect scanFrame;
    private AnimatorValue animator;
    private float animValue = 0;
    public FinderComponent(Context context) {
        super(context);
        paint = new Paint();
        possibleResultPoints = new ArrayList<>(5);
        lastPossibleResultPoints = null;


        setDrawTask();
        setAnim();

    }

    private void setAnim() {
        if (animator == null){
            animator = new AnimatorValue();
        }
        animator.setDuration(5000);
        animator.setDelay(1000);
        animator.setLoopedCount(Animator.INFINITE);
        animator.setCurveType(Animator.CurveType.CYCLE);
        animator.setValueUpdateListener(this);
    }

    private void setDrawTask() {
        addDrawTask(new DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {

                int width = getWidth();
                int height = getHeight();

                //test
                if (scanFrame == null){
                    scanFrame = new Rect();
                    scanFrame.set(250,200,width-250,height-200);
                }

                if (scanFrame != null && topRect == null){
                    topRect = new RectFloat(0, 0, width, scanFrame.top);
                    leftRect = new RectFloat(0, scanFrame.top, scanFrame.left, scanFrame.bottom + 1);
                    rightRect = new RectFloat(scanFrame.right + 1, scanFrame.top, width, scanFrame.bottom + 1);
                    bottomRect = new RectFloat(0, scanFrame.bottom + 1, width, height);
                }

                if (topRect != null && !result){
                    paint.setColor(Color.BLUE);
//                    paint.setColor(new Color(result ? resultColor : maskColor));
                    canvas.drawRect(topRect, paint);
                    canvas.drawRect(leftRect, paint);
                    canvas.drawRect(rightRect, paint);
                    canvas.drawRect(bottomRect, paint);
                }

                if (resultPixelMapHolder != null && result){
                    paint.setAlpha(CURRENT_POINT_OPACITY);
                    if (resultPixelMapHolder.getPixelMap() != null){
                        canvas.drawPixelMapHolder(resultPixelMapHolder,scanFrame.left,scanFrame.top, paint);
                    }
                }else if(scanFrame != null){
                    paint.setColor(new Color(laserColor));
//                    paint.setColor(Color.RED);
                    int lenght = scanFrame.bottom - scanFrame.top - 5;

                    Point startPoint = new Point(scanFrame.left,scanFrame.top+lenght*animValue +2);
                    Point endPoint = new Point(scanFrame.right,scanFrame.top+lenght*animValue +2);
                    canvas.drawLine(startPoint,endPoint,paint);

                }
            }
        }, DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
    }

    public FinderComponent(Context context, AttrSet attrSet) {
        super(context);

    }

    public void setCameraManager(CameraManager manager){
        this.cameraManager = manager;

        int width = getWidth();
        int height = getHeight();
        scanFrame = cameraManager.getFramingRect();
//        frame.set(150,200,width-150,height-200);

        topRect = new RectFloat(0, 0, width, scanFrame.top);
        leftRect = new RectFloat(0, scanFrame.top, scanFrame.left, scanFrame.bottom + 1);
        rightRect = new RectFloat(scanFrame.right + 1, scanFrame.top, width, scanFrame.bottom + 1);
        bottomRect = new RectFloat(0, scanFrame.bottom + 1, width, height);
    }

    public void animStart() {
        setAnim();
        if (animator != null && !animator.isRunning()){
            animator.start();
        }
    }

    public void stopAnim(){
        if (animator != null){
            animator.stop();
        }
    }

    public void drawResultBitmap(PixelMap barcode) {
        resultPixelMapHolder = new PixelMapHolder(barcode);
        result = true;
        stopAnim();
        invalidate();
    }

    public void drawViewfinder() {
        resultPixelMapHolder.resetPixelMap(resultPixelMapHolder.getPixelMap());
        resultPixelMapHolder = null;
        result = false;
        animStart();
        invalidate();
    }


    @Override
    public void onUpdate(AnimatorValue animatorValue, float v) {
            animValue = Math.abs(v);
            invalidate();
    }
}
